Skip to content

[ZEPPELIN-6481] Restore interrupt status after InterruptedException in JDBC completion loading#5288

Merged
jongyoul merged 1 commit into
apache:masterfrom
HwangRock:ZEPPELIN-6481-pr
Jul 12, 2026
Merged

[ZEPPELIN-6481] Restore interrupt status after InterruptedException in JDBC completion loading#5288
jongyoul merged 1 commit into
apache:masterfrom
HwangRock:ZEPPELIN-6481-pr

Conversation

@HwangRock

Copy link
Copy Markdown
Contributor

What is this PR for?

The catch (InterruptedException e) block around awaitTermination(...) in createOrUpdateSqlCompleter(...) in JDBCInterpreter logs a warning and closes the connection, but never restores the interrupt status. Catching InterruptedException clears the thread's interrupt flag, so the interrupt is swallowed: callers on the completion request path can no longer detect it, and cooperative cancellation and shutdown signals are silently dropped. This is the classic swallowed-interrupt anti-pattern.

This restores the interrupt with Thread.currentThread().interrupt() as the last statement of the block, after the connection-close attempt. Placing it last keeps the existing resource-release behavior running first, then leaves the interrupt status intact when the method returns so the calling thread can detect it.

What type of PR is it?

Bug Fix

Todos

  • Restore interrupt status in the InterruptedException catch block
  • Add a unit test covering the restored interrupt status

What is the Jira issue?

How should this be tested?

  • ./mvnw test -pl jdbc -Dtest=JDBCInterpreterTest
  • New test testCreateOrUpdateSqlCompleterRestoresInterruptStatusOnTimeout pre-interrupts the calling thread so awaitTermination(...) throws InterruptedException immediately, drives the completer through the catch path, and asserts Thread.currentThread().isInterrupted() is true on return. Before the fix the flag is cleared and the assertion fails; after the fix it passes. 32 tests in the class pass.

Screenshots (if appropriate)

N/A

Questions:

  • Does the license files need to update? No.
  • Is there breaking changes for older versions? No.
  • Does this needs documentation? No.

…n JDBC completion loading

The catch (InterruptedException e) block around awaitTermination(...) in
createOrUpdateSqlCompleter(...) logged a warning and closed the connection but
never restored the interrupt status. Catching InterruptedException clears the
thread's interrupt flag, so the interrupt was swallowed and callers on the
completion request path could no longer detect it, silently dropping
cooperative cancellation and shutdown signals.

Restore the interrupt status with Thread.currentThread().interrupt() as the
last statement of the catch block, after the connection-close attempt. Add a
unit test that pre-interrupts the calling thread, drives the completer through
the catch path, and asserts the interrupt flag is restored on return.

@ParkGyeongTae ParkGyeongTae left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. +1

@jongyoul jongyoul merged commit dfd8cf7 into apache:master Jul 12, 2026
18 of 19 checks passed
@jongyoul

Copy link
Copy Markdown
Member

Merged into master (dfd8cf7).

jongyoul pushed a commit that referenced this pull request Jul 14, 2026
### What is this PR for?

`NoteManager.removeFolder` removed the deleted notes from `notesInfo` and the in-memory folder tree, but never evicted them from the `NoteCache`. `removeNote(String, AuthenticationInfo)` already calls `noteCache.removeNote(noteId)`, so the single-note path is clean; the folder path was not. As a result the `Note` objects for deleted notes stayed on the heap until the LRU threshold naturally evicted them, and they kept occupying cache slots that live notes could otherwise use. This is most wasteful for large folder deletions such as emptying the trash.

This PR evicts each removed note from `noteCache` in the same loop that clears `notesInfo`, mirroring the single-note removal path. There is no functional/correctness change (`processNote` already gates on `notesInfo.containsKey`), only immediate reclamation of the cache slots and heap held by deleted notes.

This was found by <at>ParkGyeongTae while reviewing #5288 / #5292 (ZEPPELIN-6345).

### What type of PR is it?
Improvement

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-6529

### How should this be tested?
* Added `NoteManagerTest#testRemoveFolderEvictsNoteCache`: adds two notes under `/folder1`, asserts `getCacheSize() == 2`, calls `removeFolder("/folder1", ...)`, and asserts `getCacheSize() == 0`. Fails before the change (cache size stays `2`), passes after.
* Full `NoteManagerTest` passes (6 tests), including `testLruCache` and `testNoteOperations`.

### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Closes #5296 from HwangRock/ZEPPELIN-6529-pr.

Signed-off-by: Jongyoul Lee <jongyoul@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants